#include "svn_types.h"
#include <string.h>
#include <stdio.h>
#include <math.h>
#include "bdb/dbt.h"
#include "bdb/env.h"
#include "table.h"
#include "fs.h"

#include "bdb/chimaera_user-table.h"
#include "bdb/chimaera_certificate-table.h"
#include "bdb/chimaera_project-table.h"
#include "bdb/chimaera_message_index-table.h"
#include "bdb/chimaera_message-table.h"
#include "bdb/chimaera_file-table.h"
#include "bdb/chimaera_group-table.h"
#include "bdb/chimaera_user_index-table.h"

#include "chimaera_user.h"
#include "fs-loader.h"

#include "util/fs_skels.h"
#include "openssl/x509.h"
#include "openssl/pem.h"

/*
 * To use transactions, you should specify DB_AUTO_COMMIT 
 * to the DB_ENV->set_flags() or DB->open() method.
 *
 * I use nearly six hours to find this.
 * 2009.05.01 it's festival:(
 *
 * In bdb manual, if not use set_alloc() methods to pass BDB 
 * references to the application's allocation routines, 
 * transferring memory between lib and application will fail 
 * because they use different heaps...
 *
 * I use 4 hours to find this.
 * 2009.05.02
 */

BOOL
open_env(DB_ENV **env)
{
	int ret;
	u_int32_t flags;

	ret = db_env_create(env, 0);

	if (ret != 0){
        printf("%s\n","create env error");
		return FALSE;
	}

	(*env)->set_flags(*env,DB_AUTO_COMMIT,1);
	(*env)->set_alloc(*env,malloc,realloc,free);
	flags = DB_CREATE|DB_INIT_MPOOL|DB_INIT_TXN|DB_INIT_LOCK|DB_INIT_LOG|DB_PRIVATE;

	ret = (*env)->open(*env,"..\\ChimaeraServe\\Debug\\repos4debug\\db",flags,0);

	if (ret != 0){
		ret = (*env)->open(*env,"..\\..\\ChimaeraServe\\Debug\\repos4debug\\db",flags,0);
		if (ret != 0)
		{
			printf("%s\n","open env error");
			return FALSE;
		}
		
	}

	return TRUE;
}

int open_tables(chimaera_tables_t *ctables,DB_ENV *env)
{
	
	svn_fs_bdb__open_chimaera_certificate_table(
		&(ctables->chimaera_certificate),
		env,FALSE);
	
	svn_fs_bdb__open_chimaera_user_index_table(
		&(ctables->chimaera_user_index),
		env,FALSE);

	svn_fs_bdb__open_chimaera_file_table(
		&(ctables->chimaera_file),
		env,FALSE);

	svn_fs_bdb__open_chimaera_group_table(
		&(ctables->chimaera_group),
		env,FALSE);

	svn_fs_bdb__open_chimaera_message_table(
		&(ctables->chimaera_message),
		env,FALSE);

	svn_fs_bdb__open_chimaera_message_index_table(
		&(ctables->chimaera_message_index),
		env,FALSE);

	svn_fs_bdb__open_chimaera_project_table(
		&(ctables->chimaera_project),
		env,FALSE);

	svn_fs_bdb__open_chimaera_user_table(
		&(ctables->chimaera_user),
		env,FALSE);

	return 1;
}

int close_tables(chimaera_tables_t *ctables)
{

	ctables->chimaera_certificate->close(
			   ctables->chimaera_certificate,0);

	ctables->chimaera_user_index->close(
				ctables->chimaera_user_index,0);

	ctables->chimaera_file->close(
					  ctables->chimaera_file,0);

	ctables->chimaera_group->close(
					 ctables->chimaera_group,0);

	ctables->chimaera_message->close(
				   ctables->chimaera_message,0);

	ctables->chimaera_message_index->close(
			 ctables->chimaera_message_index,0);

	ctables->chimaera_project->close(
				   ctables->chimaera_project,0);

	ctables->chimaera_user->close(
					  ctables->chimaera_user,0);

	return 1;


}
BOOL get_message(chimaera_tables_t *catable, char* num)
{
	int ret;
	DBC *cursor = 0;
	int i=0;
	DBT key, value;
	chimaeramessage_t *temp;
	char *time;

	catable->chimaera_message_index->cursor(
							catable->chimaera_message_index,
											NULL,&cursor,0);


	temp = (chimaeramessage_t *)malloc(sizeof(*temp));

	memset(&key,0,sizeof(DBT));
	memset(&value,0,sizeof(DBT));


	time = (char *)malloc(30);

	while((ret = svn_bdb_dbc_get(cursor,&key,&value,DB_NEXT)) == 0)
	{

		memcpy(&(temp->user_recno),key.data,key.size);
		memcpy(&(temp->message_id),value.data,value.size);

		printf("recno:%d : user:%d %d %d %d %d - ",++i,temp->user_recno,
			temp->need_confirm,temp->read,temp->confirmed,temp->message_id);
		apr_ctime(time,temp->born_time);
		printf("%s - ",time);
		apr_ctime(time,temp->read_time);
		printf("%s - ",time);
		apr_ctime(time,temp->confirm_time);
		printf("%s \n",time);

		if (temp->message_id==5)
		{
			svn_bdb_dbc_del(cursor,0);
		}
	}

	free(time);
	free(temp);
	if (cursor)
	{
		svn_bdb_dbc_close(cursor);
	}

	return TRUE;
}

BOOL list_user(chimaera_tables_t *catable, char* num)
{
	int ret;
	DBC *cursor = 0;
	DBT key, value;
	chimaerauser_t *temp;
	skel_t *skel;
	apr_pool_t *pool;

	catable->chimaera_user->cursor(
		catable->chimaera_user,
		NULL,&cursor,0);

	temp = (chimaerauser_t *)malloc(sizeof(*temp));
	apr_pool_initialize();
	apr_pool_create(&pool,NULL);

	memset(&key,0,sizeof(DBT));
	memset(&value,0,sizeof(DBT));

	while((ret = svn_bdb_dbc_get(cursor,&key,&value,DB_NEXT)) == 0){

		/* Parse the chimaerauser skel.  */
		skel = svn_fs_base__parse_skel(value.data, value.size, pool);

		/* Convert to a native type.  */
		svn_fs_base__parse_chimaerauser_skel(&temp, skel, pool);

		*((char *)(value.data)+value.size) = '\x00';

		printf("user %d: %s\n%s\n",*(int *)key.data,temp->username,value.data);
	}

	catable->chimaera_user_index->cursor(
		catable->chimaera_user_index,
		NULL,&cursor,0);

	memset(&key,0,sizeof(DBT));
	memset(&value,0,sizeof(DBT));

	while((ret = svn_bdb_dbc_get(cursor,&key,&value,DB_NEXT)) == 0){

		printf("userid: %s\n%d\n",key.data,*(int *)value.data);
	}

	catable->chimaera_certificate->cursor(
		catable->chimaera_certificate,
		NULL,&cursor,0);

	memset(&key,0,sizeof(DBT));
	memset(&value,0,sizeof(DBT));

	while((ret = svn_bdb_dbc_get(cursor,&key,&value,DB_NEXT)) == 0){

		printf("certificate: %d\n%d\n",*(int *)key.data,value.size);
	}
	
	apr_pool_destroy(pool);

	if (cursor)
	{
		svn_bdb_dbc_close(cursor);
	}
	
	return TRUE;

}
/* list project*/
BOOL list_project(chimaera_tables_t *catable, char* num)
{
	int ret;
	DBC *cursor = 0;
	DBT key, value;
	chimaeraproject_t *temp;
	skel_t *skel;
	apr_pool_t *pool;

	catable->chimaera_project->cursor(
		catable->chimaera_project,
		NULL,&cursor,0);

	temp = (chimaeraproject_t *)malloc(sizeof(*temp));
	apr_pool_initialize();
	apr_pool_create(&pool,NULL);

	memset(&key,0,sizeof(DBT));
	memset(&value,0,sizeof(DBT));

	while((ret = svn_bdb_dbc_get(cursor,&key,&value,DB_NEXT)) == 0){

		/* Parse the chimaeraproject skel.  */
		skel = svn_fs_base__parse_skel(value.data, value.size, pool);

		/* Convert to a native type.  */
		svn_fs_base__parse_chimaeraproject_skel(&temp, skel, pool);

		*((char *)(value.data)+value.size) = '\x00';

		printf("project: %d: %s\n%s\n",*(int *)key.data,temp->project_name,value.data);
	}

	apr_pool_destroy(pool);

	if (cursor)
	{
		svn_bdb_dbc_close(cursor);
	}

	return TRUE;

}

BOOL put_user(chimaera_tables_t *ctable, char* num)
{

	chimaerauser_t *cuser;

	apr_pool_t *pool;
	char *buffer;
	FILE *cafile;
	apr_int32_t cert_len;
	void *certificate_from_localfile;
	svn_string_t *userid;
	chimaeracertificate_t *ccertificate;
	char *username;
	char *userinfo;

	X509 *x509certificate;
	ASN1_INTEGER *op;

	svn_revnum_t id = -1;
	svn_fs_t *fs;

	db_recno_t recno = 0;
	/*
	int db_err;
	DBT key,value;
	DB_TXN *txn;
	*/
	
	
	

	cuser = malloc(sizeof(*cuser));
	buffer = malloc(1024);

	apr_pool_initialize();
	apr_pool_create(&pool,NULL);

	/* USERNAME */
	printf("prepare for add a user, first input the user name:\n");
	scanf("%s",buffer);
	*(buffer+1023) = '\x00';
	username = apr_palloc(pool,strlen(buffer)+1);
	strcpy(username,buffer);
	cuser->username = username;

	/* CERTIFICATE and USERID*/
	printf("input the path of certificate:\n");
	scanf("%s",buffer);
	*(buffer+1023) = '\x00';

	cafile = fopen(buffer,"rb");

	if (cafile == NULL)
	{
		printf("file doesn't exist, check the path!");
		return 0;
	}

	if (!fseek(cafile,0,SEEK_END))
	{
		cert_len = ftell(cafile);
		if (cert_len == -1)
		{
			return 0;
		}
		certificate_from_localfile = apr_palloc(pool,cert_len);
		fseek(cafile,0,SEEK_SET);
		fread(certificate_from_localfile,cert_len,1,cafile);
	}

	ccertificate = apr_pcalloc(pool, sizeof(*ccertificate));
	ccertificate->certificate=certificate_from_localfile;
	ccertificate->len=cert_len;
	cuser->certificate=ccertificate;
	
	/* USERID */
	fseek(cafile,0,SEEK_SET);
	if (1)
	{
		/* support postfix .pem .der*/
		char *cmp1 = ".pem";
		char *cmp2 = ".der";
		//char *cmp3 = ".crt";

		if(!strcmp(cmp1,buffer+strlen(buffer)-4))
			x509certificate = 
				PEM_read_X509(cafile,NULL,NULL,NULL);
		else if(!strcmp(cmp2,buffer+strlen(buffer)-4))
			x509certificate = d2i_X509_fp(cafile, NULL);
		else
		{
			printf("only .der or .pem file is supported!\n");
			return 0;
		}
		
	}
	op = X509_get_serialNumber(x509certificate);

	userid=malloc(sizeof(*userid));
	userid->data = op->data;
	userid->len = op->length;
	cuser->userid=userid;
	
	/* USER CHARACTERS*/
	printf("input the user character:\n1:sysuser\n2:boss\n3:manager\n4:group leader\n5:group member\n");
	scanf("%s",buffer);
	*(buffer+1023) = '\x00';

	switch(*buffer){
		case '1':
			cuser->sysuser=1;
			cuser->character=0;
			break;
		case '2':
			cuser->sysuser=0;
			cuser->character=1;
			break;
		case '3':
			cuser->sysuser=0;
			cuser->character=2;
			break;
		case '4':
			cuser->sysuser=0;
			cuser->character=3;
			break;
		case '5':
			cuser->sysuser=0;
			cuser->character=4;
			break;
		default:
			printf("invalid input!");
			return 0;
	}

	/* USER CHARACTERS*/
	printf("input the user info:\n");
	scanf("%s",buffer);
	*(buffer+1023) = '\x00';
	userinfo = apr_palloc(pool,strlen(buffer)+1);
	strcpy(userinfo,buffer);
	cuser->userinfo = userinfo;

	cuser->ticket=NULL;

	
	constrct_fs_from_ctable(ctable,&fs,pool);
	svn_fs_base__set_chimaera_user(cuser,&id,fs,pool);

	
	/*
		ctable->env->txn_begin(ctable->env,NULL,&txn,0);
			svn_fs_base__recno_dbt(&key, &recno);
			svn_fs_base__set_dbt(&value, ccertificate->certificate, ccertificate->len);
		
			db_err = ctable->chimaera_certificate->put(ctable->chimaera_certificate, txn,
				&key,&value,DB_APPEND);
		

	txn->commit(txn,0);
	*/							
		
	

	free(userid);
	free(cuser);
	free(buffer);
	if (cafile != NULL)
		fclose(cafile);
	apr_pool_destroy(pool);
	return TRUE;

}
/* num> 0 edit or put new*/
BOOL put_project(chimaera_tables_t *ctable, char* num)
{
	int ret;
	DBC *cursor = NULL;
	chimaeraproject_t *cproject;
	apr_pool_t *pool;
	svn_fs_t *fs;
	char *buffer;
	char *pname,*path,*gl,*group,*proinfo,*creator;

	ret = atoi(num);
	apr_pool_initialize();
	apr_pool_create(&pool,NULL);

	constrct_fs_from_ctable(ctable,&fs,pool);
	buffer = calloc(1024,sizeof(*buffer));
	//cproject = apr_pcalloc(pool,sizeof(*cproject));


	if (ret>0)
	{
		svn_revnum_t id=ret;
		//edit the record
		svn_fs_bdb__get_chimaera_project(&cproject,ret,fs,pool);

		//edit project_name
		printf("edit BEGIN, original name:%s\nnow input:\n",cproject->project_name);
		scanf("%s",buffer);
		*(buffer+1023) = '\x00';
		pname = apr_palloc(pool,strlen(buffer)+1);
		strcpy(pname,buffer);
		cproject->project_name = pname;

		//edit root_path
		printf("original path:%s\nnow input:\n",cproject->root_path);
		scanf("%s",buffer);
		*(buffer+1023) = '\x00';
		path = apr_palloc(pool,strlen(buffer)+1);
		strcpy(path,buffer);
		cproject->root_path = path;

		//edit gl
		printf("original group_leader:%s\nnow input:\n",cproject->group_leader);
			scanf("%s",buffer);
		*(buffer+1023) = '\x00';
		gl = apr_palloc(pool,strlen(buffer)+1);
		strcpy(gl,buffer);
		cproject->group_leader = gl;

		//edit group
		printf("original group:\n%s\nnow input:",cproject->group);
		scanf("%s",buffer);
		*(buffer+1023) = '\x00';
		group = apr_palloc(pool,strlen(buffer)+1);
		strcpy(group,buffer);
		cproject->group = group;

		//edit proinfo
		printf("original pinfo: %s\nnow: \n",cproject->pinfo);
		scanf("%s",buffer);
		*(buffer+1023) = '\x00';
		proinfo = apr_palloc(pool,strlen(buffer)+1);
		strcpy(proinfo,buffer);
		cproject->pinfo = proinfo;

		//edit creator
		printf("original creator: %s\nnow input the new one:\n",cproject->creator);
		scanf("%s",buffer);
		*(buffer+1023) = '\x00';
		creator = apr_palloc(pool,strlen(buffer)+1);
		strcpy(creator,buffer);
		cproject->creator = creator;

		svn_fs_bdb__put_chimaera_project(cproject,&id,fs,NULL,pool);

	}
	else
	{
		svn_revnum_t id=-1;
		//new a record
		cproject = apr_pcalloc(pool,sizeof(*cproject));

		//edit project_name
		printf(" name now input:\n");
		scanf("%s",buffer);
		*(buffer+1023) = '\x00';
		pname = apr_palloc(pool,strlen(buffer)+1);
		strcpy(pname,buffer);
		cproject->project_name = pname;

		//edit root_path
		printf("path now input:\n");
		scanf("%s",buffer);
		*(buffer+1023) = '\x00';
		path = apr_palloc(pool,strlen(buffer)+1);
		strcpy(path,buffer);
		cproject->root_path = path;

		//edit gl
		printf("group_leader now input:\n");
		scanf("%s",buffer);
		*(buffer+1023) = '\x00';
		gl = apr_palloc(pool,strlen(buffer)+1);
		strcpy(gl,buffer);
		cproject->group_leader = gl;

		//edit group
		printf("group now input:");
		scanf("%s",buffer);
		*(buffer+1023) = '\x00';
		group = apr_palloc(pool,strlen(buffer)+1);
		strcpy(group,buffer);
		cproject->group = group;

		//edit proinfo
		printf("pinfo now input: \n");
		scanf("%s",buffer);
		*(buffer+1023) = '\x00';
		proinfo = apr_palloc(pool,strlen(buffer)+1);
		strcpy(proinfo,buffer);
		cproject->pinfo = proinfo;

		//edit creator
		printf("creator now input :\n");
		scanf("%s",buffer);
		*(buffer+1023) = '\x00';
		creator = apr_palloc(pool,strlen(buffer)+1);
		strcpy(creator,buffer);
		cproject->creator = creator;

		cproject->time_nodes_num=0;

		svn_fs_bdb__put_chimaera_project(cproject,&id,fs,NULL,pool);

	}

	free(buffer);
	apr_pool_destroy(pool);

	if (cursor)
	{
		svn_bdb_dbc_close(cursor);
	}

	return TRUE;

}
BOOL put_group(chimaera_tables_t *ctable, char* num)
{
	int ret;
	DBC *cursor = NULL;
	apr_int32_t *groupm,*first;
	apr_pool_t *pool;
	svn_fs_t *fs;
	int member_bum,temp;
	int i;
	svn_revnum_t id=-1;

	ret = atoi(num);
	apr_pool_initialize();
	apr_pool_create(&pool,NULL);

	constrct_fs_from_ctable(ctable,&fs,pool);

	printf("input the amount of members\n");
	scanf("%d",&member_bum);
	groupm = malloc(member_bum*sizeof(*groupm));

	for (i=1,first=groupm;i<member_bum+1;i++)
	{
		printf("input member %d 's id of the all %d members\n",i,member_bum);
		scanf("%d",&temp);
		*first++ = temp;
	}

	svn_fs_bdb__put_chimaera_group(&id,groupm,member_bum,fs,NULL,pool);

	return TRUE;

}
BOOL list_group(chimaera_tables_t *catable, char* num)
{
	int ret;
	DBC *cursor = 0;
	DBT key, value;
	apr_int32_t *temp;

	catable->chimaera_project->cursor(
		catable->chimaera_group,
		NULL,&cursor,0);

	memset(&key,0,sizeof(DBT));
	memset(&value,0,sizeof(DBT));

	while((ret = svn_bdb_dbc_get(cursor,&key,&value,DB_NEXT)) == 0){

		int i;
		printf("group number: %d\n",*(int *)key.data);
		for(i=0,temp = value.data;i<floor(value.size/sizeof(apr_int32_t));i++,temp++){
			printf("%d, ",*temp);
		}
		
	}


	if (cursor)
	{
		svn_bdb_dbc_close(cursor);
	}

	return TRUE;

}

BOOL put_cer(chimaera_tables_t *ctable, char* num)
{

	apr_pool_t *pool;
	char *buffer;
	FILE *cafile;
	apr_int32_t cert_len;
	void *certificate_from_localfile;

	chimaeracertificate_t *ccertificate;




	svn_revnum_t id = -1;
	svn_fs_t *fs;

	buffer = malloc(1024);

	apr_pool_initialize();
	apr_pool_create(&pool,NULL);
	
	printf("input the path of certificate:\n");
	scanf("%s",buffer);
	*(buffer+1023) = '\x00';

	cafile = fopen(buffer,"rb");

	if (cafile == NULL)
	{
		printf("file doesn't exist, check the path!");
		return 0;
	}

	if (!fseek(cafile,0,SEEK_END))
	{
		cert_len = ftell(cafile);
		if (cert_len == -1)
		{
			return 0;
		}
		certificate_from_localfile = apr_palloc(pool,cert_len);
		fseek(cafile,0,SEEK_SET);
		fread(certificate_from_localfile,cert_len,1,cafile);
	}

	ccertificate = apr_pcalloc(pool, sizeof(*ccertificate));
	ccertificate->certificate=certificate_from_localfile;
	ccertificate->len=cert_len;

	constrct_fs_from_ctable(ctable,&fs,pool);
	svn_fs_bdb__put_chimaera_certificate(ccertificate,&id,fs,NULL,pool);


	free(buffer);
	if (cafile != NULL)
		fclose(cafile);
	apr_pool_destroy(pool);

	return TRUE;
}

BOOL put_file(chimaera_tables_t *ctable, char* num)
{
	chimaerafile_t *cfile;

	apr_pool_t *pool;
	char *buffer;
	svn_fs_t *fs;

	char *path;
	apr_int32_t project;
	apr_int32_t node_kind;
	apr_int32_t notifier;
	apr_int32_t next_editor;
	apr_int32_t set_auth;
	apr_int32_t ex_write_auth;
	apr_int32_t ex_read_auth;
	apr_int32_t sign;
	apr_int32_t founder;

	buffer = malloc(1024);
	cfile = calloc(sizeof(*cfile),1);

	apr_pool_initialize();
	apr_pool_create(&pool,NULL);

	printf("input the full path of the file :\n");
	scanf("%s",buffer);
	*(buffer+1023) = '\x00';
	path = apr_palloc(pool,strlen(buffer)+1);
	strcpy(path,buffer);
	cfile->Path = path;

	printf("input project:\n");
	scanf("%s",buffer);
	*(buffer+1023) = '\x00';
	project = atoi(buffer);
	cfile->project = project;

	printf("input the kind of node:\n1 file\n2 dir\n");
	scanf("%s",buffer);
	*(buffer+1023) = '\x00';
	node_kind = atoi(buffer);
	cfile->node_kind = node_kind;

	printf("input the group num of notifier:\n");
	scanf("%s",buffer);
	*(buffer+1023) = '\x00';
	notifier = atoi(buffer);
	cfile->notifier = notifier;

	printf("input next editor:\n");
	scanf("%s",buffer);
	*(buffer+1023) = '\x00';
	next_editor = atoi(buffer);
	cfile->next_editor = next_editor;

	printf("input set_auth:\n");
	scanf("%s",buffer);
	*(buffer+1023) = '\x00';
	set_auth = atoi(buffer);
	cfile->set_auth = set_auth;

	printf("input ex_write_auth:\n");
	scanf("%s",buffer);
	*(buffer+1023) = '\x00';
	ex_write_auth = atoi(buffer);
	cfile->ex_write_auth = ex_write_auth;

	printf("input ex_read_auth:\n");
	scanf("%s",buffer);
	*(buffer+1023) = '\x00';
	ex_read_auth = atoi(buffer);
	cfile->ex_read_auth = ex_read_auth;

	printf("input sign:\n");
	scanf("%s",buffer);
	*(buffer+1023) = '\x00';
	sign = atoi(buffer);
	cfile->sign = sign;

	printf("input founder:\n");
	scanf("%s",buffer);
	*(buffer+1023) = '\x00';
	founder = atoi(buffer);
	cfile->founder = founder;





	
	constrct_fs_from_ctable(ctable,&fs,pool);
	svn_fs_bdb__put_chimaera_file(cfile,fs,NULL,pool);


	free(buffer);
	apr_pool_destroy(pool);

	return TRUE;
}

BOOL list_file(chimaera_tables_t *catable, char* num)
{
	int ret;
	DBC *cursor = 0;
	DBT key, value;

	chimaerafile_t *cfile = calloc(sizeof(*cfile),1);

	catable->chimaera_file->cursor(
		catable->chimaera_file,
		NULL,&cursor,0);

	memset(&key,0,sizeof(DBT));
	memset(&value,0,sizeof(DBT));

	while((ret = svn_bdb_dbc_get(cursor,&key,&value,DB_NEXT)) == 0){

		printf("path: %s\n",(char *)key.data);
		memcpy((char *)cfile+4,value.data,value.size);
		printf("project:%d == node kind:%d == ",cfile->project,cfile->node_kind);
		printf("notifier:%d == nest editor:%d == ",cfile->notifier,cfile->next_editor);
		printf("set_auth:%d == ex_w:%d == ",cfile->set_auth,cfile->ex_write_auth);
		printf("ex_r:%d == sign:%d == ",cfile->ex_read_auth,cfile->sign);
		printf("founder:%d \n",cfile->founder);

		memset(&key,0,sizeof(DBT));
		memset(&value,0,sizeof(DBT));

	}


	if (cursor)
	{
		svn_bdb_dbc_close(cursor);
	}

	return TRUE;

}

/* use ctable to construct a svn_fs_t
 * then can use current put/set functions
 */
int
constrct_fs_from_ctable(chimaera_tables_t *catable,svn_fs_t **fs,apr_pool_t *pool)
{
	svn_fs_t *fs_p;
	bdb_env_baton_t *bdb;
	base_fs_data_t *bfdt;
	bdb_error_info_t *err_t;
	svn_error_t *err=NULL;
	
	fs_p = apr_pcalloc(pool,sizeof(*fs_p));
	bdb = apr_pcalloc(pool,sizeof(*bdb));
	bfdt = apr_pcalloc(pool,sizeof(*bfdt));
	err_t = apr_pcalloc(pool,sizeof(*err_t));
	err = apr_pcalloc(pool,sizeof(*err));

	bdb->env = catable->env;
	err->pool = pool;
	err_t->pending_errors=err;
	bdb->error_info = err_t;

	bfdt->bdb = bdb;
	bfdt->chimaera_certificate = catable->chimaera_certificate;
	bfdt->chimaera_message = catable->chimaera_message;
	bfdt->chimaera_message_index = catable->chimaera_message_index;
	bfdt->chimaera_user = catable->chimaera_user;
	bfdt->chimaera_user_index = catable->chimaera_user_index;
	bfdt->chimaera_file = catable->chimaera_file;
	bfdt->chimaera_group = catable->chimaera_group;
	bfdt->chimaera_project = catable->chimaera_project;

	fs_p->fsap_data = bfdt;
	*fs = fs_p;

	return 1;

}

static const cmd_entry_t command_list[] =
{
	{"help",  help},
	{"get_message",  get_message},
	{"list_user",  list_user},
	{"put_user",  put_user},
	{"list_project",  list_project},
	{"put_project",  put_project},
	{"put_group",  put_group},
	{"list_group",  list_group},
	{"put_cer",  put_cer},
	{"put_file",  put_file},
	{"list_file",  list_file},
	{NULL}
		
};

BOOL help(chimaera_tables_t *catable, char* num)
{
	int i;

	printf("current active commands:\n");
	for (i=1;command_list[i].cmdname;i++)
	{
		printf("%d:  %s\n",i,command_list[i].cmdname);
	}
	
	return TRUE;
}

int
main(int argc, char *argv[])
{
	DB_ENV *env;
	chimaera_tables_t *ctables;
	DBC *cursor = 0;
	int i;

	if (argc != 3)
	{
		printf(" para incorrect, know more please type help");
		getc(stdin);
		return;
	}

	if (!open_env(&env))
	{
		return;
	}

	ctables = malloc(sizeof(*ctables));
	open_tables(ctables,env);
	ctables->env = env;

	/* tebles opened in env, now Let's do something 
	 *
	 * commands
	 */

	for (i=0;command_list[i].cmdname;i++)
	{
		if(strcmp(command_list[i].cmdname,argv[1]) == 0)
			break;
	}

	if (command_list[i].cmdname)
	{
		(*command_list[i].handler)(ctables,argv[2]);
	}else{
		printf("command not found, type help for more info.");
	}


	close_tables(ctables);
	free(ctables);

	if (env!=NULL)
	{
		env->close(env, 0);
	}
	
	return 1;
}